package net.expectx.micro.shop.api.manager.impl;

import net.expectx.common.single.base.BaseConstants;
import net.expectx.common.single.util.RedisUtil;
import net.expectx.micro.shop.api.common.ApiConstants;
import org.springframework.stereotype.Component;

/**
 * 使用Redis存储Token
 * @author lijian
 * @date 2017-11-04
 */
@Component
public class RedisTokenManager extends AbstractTokenManager {

    @Override
    protected void createSingleRelationship(String key, String token) {

        String oldToken = getToken(key);
        if(oldToken != null) {
            delete(formatToken(oldToken));
        }
        set(formatToken(token), key, tokenExpireSeconds);
        set(formatKey(key), token, tokenExpireSeconds);

    }

    @Override
    protected void createMultipleRelationship(String key, String token) {

        set(formatToken(token), key, tokenExpireSeconds);

    }

    @Override
    protected void delSingleRelationshipByKey(String key) {

        String token = getToken(key);
        if(token != null) {
            delete(formatKey(key), formatToken(token));
        }

    }

    @Override
    protected String getKeyByToken(String token) {

        return get(formatToken(token));

    }

    @Override
    protected void flushExpireAfterOperation(String key, String token) {

        if(singleTokenWithUser) {
            expire(formatToken(token), tokenExpireSeconds);
            expire(formatKey(key), tokenExpireSeconds);
        } else {
            expire(formatToken(token), tokenExpireSeconds);
        }

    }

    @Override
    public void delRelationshipByToken(String token) {

        if(singleTokenWithUser) {
            String key = getKey(token);
            delete(formatKey(key), formatToken(token));
        } else {
            delete(formatToken(token));
        }

    }

    private String get(String key) {

        return RedisUtil.get(key);

    }

    private void set(String key, String value, int expireSeconds) {

        RedisUtil.set(key, value, expireSeconds);

    }

    private void expire(String key, int expireSeconds) {

        RedisUtil.expire(key, expireSeconds);

    }

    private void delete(String... keys) {

        for(String key : keys) {
            RedisUtil.remove(key);
        }

    }

    protected String getToken(String key) {

        return get(formatKey(key));

    }

    private String formatKey(String key) {

        return (ApiConstants.BASIC_COMMON_PROJECT_NAME+":").concat(ApiConstants.REDIS_KEY_PREFIX.concat(key));

    }

    private String formatToken(String token) {

        return (ApiConstants.BASIC_COMMON_PROJECT_NAME+":").concat(ApiConstants.REDIS_TOKEN_PREFIX.concat(token));

    }

}
